// 交集类型
// 使用条件：必须是相同的数据类型，才可能相交
{
    type A = {
        name: string;
        doIt: (a: string) => void;
    };
    type B = {
        name: string | number;
        age: number;
        doIt: (a: number, b: string) => void;
    };

    type A_and_B = A & B;

    const user: A_and_B = {
        name: 'ck',
        age: 12,
        doIt: (a: string | number, b?: string) => {
        },
        // 或者
        //doIt: (a: string) => {}
    }

    /**
     * 对象相交：属性继承+函数重载
     */
}

{
    type OrderStatus = "pending" | "completed";
    type DeliveryStatus = "completed" | "shipped";
    type Status = OrderStatus & DeliveryStatus;
    /**
     * 会一个一个进行相交
     * ('pendding' & "completed" | "shipped") | ('completed' & "completed" | "shipped" => 'completed')
     * never | 'completed'
     * =>
     * 'completed'
     */
}

{
    class Person {
        name: string;
        eat(name: string){}
    }

    class User {
        age: number;
        getName() {
            return 'user'
        };
        eat(name: string, count: number) {}
    }

    type c = Person & User;

    const c1: c = {
        name: 'ck',
        age: 18,
        getName() {
            return 'c1'
        },
        eat(name:string, count?:number) {}
    }

    // 和 对象相交一致
}

{
    // 重映射中，过滤掉keyof T中可能出现的symbol类型
    // 使用 K & string, 得到的string类型的值 
    type P<T> = {
        [K in keyof T as `get${K & string}`]: string;
    }

    const obj = {
        a: 1,
        b: "two",
        [Symbol("c")]: true
    };

    type o = typeof obj;

    // 此时，symbol类型被过滤掉了
    type p = P<o>

}

{// 参考: ts类型系统.jpg

    // 空集类型与任何类型，没有公共的交集，所有结果仍然是一个空集
    // 结论：空集与任何类型相交仍然是一个空集
    type n = unknown & never; // never
    type s = string & never; // never
    type a = any & never; // never

    // unknown 是整个类型系统中最大的类型，所以他们的交集是最小的类型
    type a1 = unknown & string & 'ck'; // 'ck'

    // 12含于number类型中, 所以，交集是12
    type num = 12 & number; // 12
    type str = 'ck' & string; // 'ck'
}